#! /usr/bin/env node
/*
 * @Author: colpu
 * @Date: 2025-03-29 17:57:34
 * @LastEditors: colpu ycg520520@qq.com
 * @LastEditTime: 2025-04-02 16:48:22
 *
 * Copyright (c) 2025 by colpu, All Rights Reserved.
 */
/**
 * @Author: colpu
 * @Date: 2025-03-29 17:57:34
 * @LastEditors: colpu ycg520520@qq.com
 * @LastEditTime: 2025-05-30 12:38:05
 * @Description 构建、开发命令入口
 * @cmd npm run xxx
 * dev | build | production
 * 本地开发 | 发布打包 | 运行生成环境
 * @Copyright (c) 2025 by colpu, All Rights Reserved.
 */
import inquirer from "inquirer";
import shell from "shelljs"; // 脚本执行
import { loadFile } from "./utils/index.js";
const resolve = import.meta.resolve;
export default class Cli {
  constructor(options) {
    const DEFAULT = {
      modes: ["service", "deploy", "daemon", "shipit"], // 构建模式
      env_config: {
        local: "局域网环境(local)",
        preview: "测试环境(preview)",
        release: "预发布环境(release)",
        production: "正式环境(production)",
        exit: "退出",
      }, //环境配置
    };
    this.options = Object.assign(DEFAULT, options);
    const ENV_CONFIG = this.options.env_config;
    this.choices = Object.values(ENV_CONFIG);
    this.envs = Object.keys(ENV_CONFIG);
    this.argv = process.argv.slice(2); // 获取命令行参数
    this.init();
  }

  async init() {
    const _this = this;
    const argv = _this.argv;
    const modes = _this.options.modes;
    const envs = _this.envs;
    const command = argv[0]; // 主命令
    let env = argv[1]; // 环境命令
    // 如果需要选择环境，同时环境命令不在指定范围的，需要提示并将选择好环境变量装入到对应位置
    const isSelectENV = !env && modes.includes(command);
    if (isSelectENV) {
      env = _this.exactInquirer();
      if (env === "exit") {
        shell.exit();
      }
      argv.splice(1, 0, env); // 将环境变量装入
    }

    const envIndex = argv.indexOf(env); // 环境变量在argv的位置
    if (envIndex > -1 && isSelectENV) {
      argv.splice(0, envIndex + 1);
    }
    // 规范开发环境变量，非指定envs变量都为development
    if (envs.indexOf(env) === -1) {
      env = "development";
    }
    await _this.loadCommand(command, env, argv);
  }
  async loadCommand(command, env = "development", argv = []) {
    const handdle = await loadFile(resolve(`./command/${command}.js`));
    handdle(env, argv.join(" "));
  }

  /**
   * @function exactInquirer 执行用户交互提示
   * @description 当用户输入的命令不环境不完全时，进行提示
   * @return {String} 环境参数
   */
  async exactInquirer() {
    const choices = this.choices;
    const promptList = [
      {
        type: "rawlist",
        message: "靠谱少年，请选择需要的执行环境: ",
        name: "mode",
        choices,
      },
    ];
    const { mode } = await inquirer.prompt(promptList);
    return this.envs[choices.indexOf(mode)];
  }
}
